libc - aligned_alloc

void* aligned_alloc(size_t alignment, size_t size);
  1. ​Alignment Parameter​​:

    • ​Must be a power of two​​: alignment == 2^n (2, 4, 8, 16, ..., 4096, etc.)

    • ​Minimum value​​: At least sizeof(void*) (8 bytes on 64-bit systems)

    • ​No upper limit​​: But practically limited by system architecture

  2. ​Size Parameter​​:

    • ​Must be multiple of alignment​​: size % alignment == 0

    • ​Non-zero​​: Must request >0 bytes

  3. ​Return Value​​:

    • Success: Returns pointer to allocated memory

    • Failure: Returns NULL and sets errno to:

      • EINVAL: Invalid parameters

      • ENOMEM: Insufficient memory

Code example:

use std::{ptr::NonNull, slice};

fn aligned_alloc(alignment: usize, size: usize) -> Result, &'static str> {
    if alignment == 0 || (alignment & (alignment - 1)) != 0 {
        return Err("Alignment must be a power of two");
    }
    if alignment < size_of::() {
        return Err("Alignment must be at least platform pointer size");
    }
    if size == 0 || size % alignment != 0 {
        return Err("Size must be multiple of alignment");
    }

    let ptr = unsafe { libc::aligned_alloc(alignment, size) as *mut u8 };
    if ptr.is_null() {
        return Err("Memory allocation failed");
    }

    if (ptr as usize) % alignment != 0 {
        unsafe { libc::free(ptr as *mut libc::c_void) };
        return Err("Returned pointer is not properly aligned");
    }
    Ok(unsafe { NonNull::new_unchecked(ptr) })
}

fn main() {
    let page_size = unsafe { libc::sysconf(libc::_SC_PAGESIZE) } as usize;

    let size = 2 * page_size;
    let ptr = match aligned_alloc(page_size, size) {
        Ok(p) => p,
        Err(e) => panic!("Allocation err: {e:?}"),
    };
    let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), size) };
    slice.fill(1);

    println!("slice: {}", slice.len());
    unsafe { libc::free(ptr.as_ptr() as *mut libc::c_void) };
}

Special attention must be paid to the fact that ​​aligned_alloc(alignment, size) strictly requires size to be an integer multiple of alignment​​. Violating this rule will result in ​​undefined behavior (UB)​​.